package com.jyw.business.obstacles.utils;

import com.aspose.words.Document;
import com.aspose.words.ImageSaveOptions;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <br>
 *
 * @author lichunjiang
 * @date 2022/5/20
 */
public class WordUtil {
    /**
     * 读取大小
     */
    private static final int BYTE_SIZE = 1024;
    /**
     * 配置信息,代码本身写的还是很可读的,就不过多注解了
     */
    private static Configuration configuration = null;
    static {
        configuration = new Configuration();
        configuration.setDefaultEncoding("UTF-8");
        configuration.setClassForTemplateLoading(WordUtil.class, "/templates");
    }

    public static boolean getLicense() {
        boolean result = false;
        try {
        	InputStream is = new ClassPathResource("license.xml").getInputStream();
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    private WordUtil() {
        throw new AssertionError();
    }

    public static File exportMillCertificateWord(Map map, String path, String ftlFile) {
        Template freemarkerTemplate = null;
        try {
            freemarkerTemplate = configuration.getTemplate(ftlFile);
            File file = createDoc(map, freemarkerTemplate, path);
            return file;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static File createDoc(Map<?, ?> dataMap, Template template, String path) {
        File f = new File(path + File.separator + "orderPrint.docx");
        Template t = template;
        try (FileOutputStream fos = new FileOutputStream(f)) {
            // 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
            Writer w = new OutputStreamWriter(fos, "utf-8");
            t.process(dataMap, w);
            w.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
        return f;
    }

    public static String getUploadPath(String path) {
        File file = new File(path);
        file.mkdirs();
        return file.getAbsolutePath();
    }

    public static void wordToPdf(String wordFile, String to) {
        FileOutputStream os = null;
        try {
            boolean license = getLicense();
            if (!license) {
                System.out.println("License验证不通过...");
                return;
            }
            //生成一个空的PDF文件
            File file = new File(to);
            os = new FileOutputStream(file);
            //要转换的word文件
            Document doc = new Document(wordFile);
            doc.save(os, SaveFormat.PDF);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void wordStreamToPdf(InputStream wordStream, String to) {
        FileOutputStream os = null;
        try {
            boolean license = getLicense();
            if (!license) {
                System.out.println("License验证不通过...");
                return;
            }
            //生成一个空的PDF文件
            File file = new File(to);
            os = new FileOutputStream(file);
            //要转换的word文件
            Document doc = new Document(wordStream);
            doc.save(os, SaveFormat.PDF);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * word 转图片
     * @param wordFile
     * @param to
     */
    public static void wordToImage(File wordFile, String to) {
        InputStream inStream = null;
        BufferedImage mergeImage = null;
        try {

            inStream = new FileInputStream(wordFile);
            List<BufferedImage> wordToImg = wordToImg(inStream);//
            mergeImage = mergeImage(false, wordToImg);
            //将其保存在C:/imageSort/targetPIC/下
            ImageIO.write(mergeImage, "jpg", new File(to));
            // wordFile.delete();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (inStream != null) {
                try {
                    inStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    /**
     * @Description: word和txt文件转换图片
     */
    private static List<BufferedImage> wordToImg(InputStream inputStream) throws Exception {
        if (!getLicense()) {
            return null;
        }
        try {
            long old = System.currentTimeMillis();
            Document doc = new Document(inputStream);
            ImageSaveOptions options = new ImageSaveOptions(SaveFormat.PNG);
            options.setPrettyFormat(true);
            options.setUseAntiAliasing(true);
            options.setUseHighQualityRendering(true);
            int pageCount = doc.getPageCount();

            List<BufferedImage> imageList = new ArrayList<BufferedImage>();
            for (int i = 0; i < pageCount; i++) {
                OutputStream output = new ByteArrayOutputStream();
                options.setPageIndex(i);
                doc.save(output, options);
                ImageInputStream imageInputStream = ImageIO.createImageInputStream(parse(output));
                imageList.add(ImageIO.read(imageInputStream));

            }
            return imageList;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    //outputStream转inputStream
    public static ByteArrayInputStream parse(OutputStream out) throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        baos = (ByteArrayOutputStream) out;
        ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray());
        return swapStream;
    }

    /**
     * 合并任数量的图片成一张图片
     *
     * @param isHorizontal true代表水平合并，fasle代表垂直合并
     * @param imgs         待合并的图片数组
     * @return
     * @throws IOException
     */
    public static BufferedImage mergeImage(boolean isHorizontal, List<BufferedImage> imgs) throws IOException {
        // 生成新图片
        BufferedImage destImage = null;
        // 计算新图片的长和高
        int allw = 0, allh = 0, allwMax = 0, allhMax = 0;
        // 获取总长、总宽、最长、最宽
        for (int i = 0; i < imgs.size(); i++) {
            BufferedImage img = imgs.get(i);
            allw += img.getWidth();

            if (imgs.size() != i + 1) {
                allh += img.getHeight() + 5;
            } else {
                allh += img.getHeight();
            }


            if (img.getWidth() > allwMax) {
                allwMax = img.getWidth();
            }
            if (img.getHeight() > allhMax) {
                allhMax = img.getHeight();
            }
        }
        // 创建新图片
        if (isHorizontal) {
            destImage = new BufferedImage(allw, allhMax, BufferedImage.TYPE_INT_RGB);
        } else {
            destImage = new BufferedImage(allwMax, allh, BufferedImage.TYPE_INT_RGB);
        }
        Graphics2D g2 = (Graphics2D) destImage.getGraphics();
        g2.setBackground(Color.LIGHT_GRAY);
        g2.clearRect(0, 0, allw, allh);
        g2.setPaint(Color.RED);

        // 合并所有子图片到新图片
        int wx = 0, wy = 0;
        for (int i = 0; i < imgs.size(); i++) {
            BufferedImage img = imgs.get(i);
            int w1 = img.getWidth();
            int h1 = img.getHeight();
            // 从图片中读取RGB
            int[] ImageArrayOne = new int[w1 * h1];
            ImageArrayOne = img.getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 逐行扫描图像中各个像素的RGB到数组中
            if (isHorizontal) { // 水平方向合并
                destImage.setRGB(wx, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
            } else { // 垂直方向合并
                destImage.setRGB(0, wy, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
            }
            wx += w1;
            wy += h1 + 5;
        }


        return destImage;
    }

    public static MultipartFile fileToMultipartFile(File file)  {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item=factory.createItem(file.getName(), MediaType.MULTIPART_FORM_DATA_VALUE,true,file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        MultipartFile multipartFile = new CommonsMultipartFile(item);
        return  multipartFile;

    }

    public static MultipartFile fileToMultipartFile(File file, String fileName)  {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item=factory.createItem(fileName, MediaType.MULTIPART_FORM_DATA_VALUE,true, fileName);
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        MultipartFile multipartFile = new CommonsMultipartFile(item);
        return  multipartFile;

    }

}
